/*
 * Copyright 2009 Gordon Turner
 * Copyright 2008 Garth Shoemaker
 * 
 * This file is part of openwiimote.
 *
 * openwiimote is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * openwiimote is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public License
 * along with Wiimote Simple.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.openwiimote.event;

import org.openwiimote.Wiimote;

/**
 * Represents a wii button event.
 */
public class WiiButtonEvent extends WiiEvent
{

  final static public long ZERO = 0x00;

  final static public long ONE = 0x01;

  final static public long TWO = 0x02;

  final static public long FOUR = 0x04;

  final static public long EIGHT = 0x08;

  final static public long TEN = 0x10;

  final static public long EIGHTY = 0x80;

  private long firstByte;

  private long secondByte;

  /**
   * The java signed bytes cause problems with numbers that are greater then
   * 127.
   * 
   * For example the value for the Home button, 0x80, 'wraps' around to -128. 
   * 
   * To correct for this, the incoming bytes are ANDed with 0xFF and set to a
   * long, which will result in the expected value and the constants will work.
   *
   * Bit  Mask    First Byte  Second Byte
   *  0   0x01    D-Pad Left  Two
   *  1   0x02    D-Pad Right One
   *  2   0x04    D-Pad Down  B
   *  3   0x08    D-Pad Up    A
   *  4   0x10    Plus        Minus
   *  5   0x20    Other uses  Other uses
   *  6   0x40    Other uses  Other uses
   *  7   0x80    Unknown     Home 
   *  
   * @param w
   * @param firstByte
   * @param secondByte
   */
  public WiiButtonEvent( Wiimote w, byte firstByte, byte secondByte )
  {
    super( w );
    this.firstByte = 0xFF & firstByte;
    this.secondByte = 0xFF & secondByte;
  }

  /**
   * Returns true if the button state of the given event are identical to the 
   * button states of this event.
   * 
   * @param e
   * @return
   */
  public boolean equals( WiiButtonEvent e )
  {
    if( e == null )
    {
      return false;
    }
    else
    {
      return ( isAPressed() == e.isAPressed() && isBPressed() == e.isBPressed()
          && is1Pressed() == e.is1Pressed() && is2Pressed() == e.is2Pressed()
          && isLeftPressed() == e.isLeftPressed()
          && isRightPressed() == e.isRightPressed()
          && isDownPressed() == e.isDownPressed()
          && isUpPressed() == e.isUpPressed()
          && isMinusPressed() == e.isMinusPressed()
          && isPlusPressed() == e.isPlusPressed() && isHomePressed() == e
          .isHomePressed() );
    }
  }

  /*
   * Directional pad buttons.
   */

  public boolean isLeftPressed()
  {
    return ( firstByte == ONE && secondByte == ZERO );
  }

  public boolean isRightPressed()
  {
    return ( firstByte == TWO && secondByte == ZERO );
  }

  public boolean isDownPressed()
  {
    return ( firstByte == FOUR && secondByte == ZERO );
  }

  public boolean isUpPressed()
  {
    return ( firstByte == EIGHT && secondByte == ZERO );
  }

  /*
   * A, B, 1 and 2 buttons.
   */

  public boolean isAPressed()
  {
    return ( firstByte == ZERO && secondByte == EIGHT );
  }

  public boolean isBPressed()
  {
    return ( firstByte == ZERO && secondByte == FOUR );
  }

  public boolean is1Pressed()
  {
    return ( firstByte == ZERO && secondByte == TWO );
  }

  public boolean is2Pressed()
  {
    return ( firstByte == ZERO && secondByte == ONE );
  }

  /*
   * Other buttons.
   */

  public boolean isMinusPressed()
  {
    return ( firstByte == ZERO && secondByte == TEN );
  }

  public boolean isPlusPressed()
  {
    return ( firstByte == TEN && secondByte == ZERO );
  }

  public boolean isHomePressed()
  {
    return ( firstByte == ZERO && secondByte == EIGHTY );
  }

  /*
   * Convenince method.
   * 
   * (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  public String toString()
  {
    return new String( "WiiButtonEvent [A: " + isAPressed() + " B: "
        + isBPressed() + " 1: " + is1Pressed() + " 2: " + is2Pressed() + " L: "
        + isLeftPressed() + " R: " + isRightPressed() + " D: "
        + isDownPressed() + " U: " + isUpPressed() + " -: " + isMinusPressed()
        + " +: " + isPlusPressed() + " H: " + isHomePressed() + "]" );
  }
}
